package com.lilong.jwt.service.user.impl;

import com.google.common.collect.Lists;
import com.lilong.jwt.common.base.BaseRepository;
import com.lilong.jwt.common.base.BaseServiceImpl;
import com.lilong.jwt.common.enums.StatusEnum;
import com.lilong.jwt.common.exception.ExceptionEnum;
import com.lilong.jwt.common.exception.HydrauException;
import com.lilong.jwt.entity.user.Permission;
import com.lilong.jwt.entity.user.QRole;
import com.lilong.jwt.entity.user.Role;
import com.lilong.jwt.entity.user.User;
import com.lilong.jwt.pojo.view.PermissionTree;
import com.lilong.jwt.pojo.view.RoleVo;
import com.lilong.jwt.repository.user.PermissionRepository;
import com.lilong.jwt.repository.user.RoleRepository;
import com.lilong.jwt.service.user.RoleService;
import com.querydsl.core.types.dsl.EntityPathBase;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl extends BaseServiceImpl<Role> implements RoleService {
    @Resource
    private RoleRepository roleRepository;
    @Resource
    private PermissionRepository permissionRepository;

    @Override
    protected String getEntityMsg() {
        return "角色信息";
    }

    @Override
    protected BaseRepository<Role> getBaseRepository() {
        return roleRepository;
    }

    @Override
    protected EntityPathBase<Role> getQEntity() {
        return QRole.role;
    }

    protected void check(Role t) {
        Role role = roleRepository.findByName(t.getName());
        if (!ObjectUtils.isEmpty(role)) {
            throw new HydrauException(ExceptionEnum.ALREADY_EXIST, getEntityMsg());
        }
        super.check(t);
    }

    public int updateEntity(Role t, User operator) {
        if (!ObjectUtils.isEmpty(t.getPermissions())) {
            t.setPermissions(t.getPermissions().stream().filter(n -> !ObjectUtils.nullSafeEquals(0L, n.getId())).collect(Collectors.toList()));
        }
        return super.updateEntity(t, operator);
    }

    /**
     * 获取权限树
     *
     * @param pid         父ID
     * @param permissions 已拥有权限
     * @param allList     所有可用权限
     * @return 子权限权
     */
    private List<PermissionTree> getChildesPermissionTree(Long pid, List<Permission> permissions, List<Permission> allList) {
        List<PermissionTree> list = new ArrayList<>();
        allList.stream().filter(n -> ObjectUtils.nullSafeEquals(pid, n.getPid())).collect(Collectors.toList()).forEach(p -> {
            PermissionTree tree = new PermissionTree();
            tree.setChecked(permissions.stream().anyMatch(o -> o.getId().equals(p.getId())));
            tree.setName(p.getName());
            tree.setId(p.getId());
            tree.setChildes(getChildesPermissionTree(tree.getId(), permissions, allList));
            tree.setLeaf(tree.getChildes().size() <= 0);
            list.add(tree);
        });
        return list;
    }

    @Override
    public RoleVo findRoleVoById(Long id) {
        Role role = findById(id);
        List<Permission> allList = permissionRepository.findAll().stream().filter(n -> ObjectUtils.nullSafeEquals(n.getStatus(), StatusEnum.VALID_DATA.getValue())).collect(Collectors.toList());
        RoleVo vo = new RoleVo();
        BeanUtils.copyProperties(role, vo, "permissions");
        PermissionTree tree = new PermissionTree();
        tree.setChecked(true);
        tree.setLeaf(false);
        tree.setName("权限");
        tree.setId(0L);
        tree.setChildes(getChildesPermissionTree(tree.getId(), role.getPermissions(), allList));
        tree.setLeaf(tree.getChildes().size() <= 0);
        vo.setPermissionTree(tree);
        return vo;
    }

    @Override
    public PermissionTree getPermissionTree() {
        List<Permission> allList = permissionRepository.findAll().stream().filter(n -> ObjectUtils.nullSafeEquals(n.getStatus(), StatusEnum.VALID_DATA.getValue())).collect(Collectors.toList());
        PermissionTree tree = new PermissionTree();
        tree.setChecked(true);
        tree.setLeaf(false);
        tree.setName("权限");
        tree.setId(0L);
        tree.setChildes(getChildesPermissionTree(tree.getId(), Lists.newArrayList(), allList));
        tree.setLeaf(tree.getChildes().size() <= 0);
        return tree;
    }
}
